package site.sishidadao.morphtext;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.view.ViewGroup;
import android.widget.AbsoluteLayout;

import java.util.List;

public class CharMorphLimbo extends CharLimbo {
    public static class ExtraInfo {
        public List<MorphChar> FinalChars;
        public MorphTextview.HorizontalAlignment HorizontalAlignment;
        public int FromTotalWidth;
        public int ToTotalWidth;
        public int WidgetWidth;
        public int YPos;
    }

    protected ExtraInfo mExtraInfo;

    public CharMorphLimbo( MorphChar morphChar, long delay, long duration,
                           ExtraInfo extraInfo ) {
        super( morphChar, delay, duration );
        mExtraInfo = extraInfo;
    }

    protected MorphChar findChar4FromIdx( int fromIdx ) {
        for ( int i = 0; i < mExtraInfo.FinalChars.size( ); i++ )
            if ( mExtraInfo.FinalChars.get( i ).FromIdx == fromIdx )
                return mExtraInfo.FinalChars.get( i );
        return null;
    }

    protected MorphChar findChar4ToIdx( int toIdx ) {
        for ( int i = 0; i < mExtraInfo.FinalChars.size( ); i++ )
            if ( mExtraInfo.FinalChars.get( i ).ToIdx == toIdx )
                return mExtraInfo.FinalChars.get( i );
        return null;
    }

    protected int calXPos4FromIdx( int fromIdx ) {
        int xPos = 0;
        for ( int i = 0; i < fromIdx; i++ ) {
            MorphChar morphChar = findChar4FromIdx( i );
            xPos += morphChar.TextViewRef.getMeasuredWidth( );
        }

        switch ( mExtraInfo.HorizontalAlignment ) {
            case Left:
                return xPos;
            case Center:
                return xPos + ( mExtraInfo.WidgetWidth - mExtraInfo.FromTotalWidth ) / 2;
            case Right:
                return mExtraInfo.WidgetWidth - xPos
                        - findChar4FromIdx( fromIdx ).TextViewRef.getLayoutParams( ).width;
        }
        return -1;
    }

    protected int calXPos4ToIdx( int toIdx ) {
        int xPos = 0;
        for ( int i = 0; i < toIdx; i++ ) {
            MorphChar morphChar = findChar4ToIdx( i );
            xPos += morphChar.TextViewRef.getMeasuredWidth( );
        }

        switch ( mExtraInfo.HorizontalAlignment ) {
            case Left:
                return xPos;
            case Center:
                return xPos + ( mExtraInfo.WidgetWidth - mExtraInfo.ToTotalWidth ) / 2;
            case Right:
                return mExtraInfo.WidgetWidth - xPos
                        - findChar4ToIdx( toIdx ).TextViewRef.getLayoutParams( ).width;
        }
        return -1;
    }

    // 默认动画，原地淡出
    public void attachLeaveAnimations( List<Animator> animatiors ) {
        Animator aniAlpha = ObjectAnimator.ofFloat( mMorphChar.TextViewRef, "alpha", 1, 0 );
        aniAlpha.setDuration( mDuration );
        animatiors.add( aniAlpha );
    }

    // 默认动画，原地淡入
    public void attachEnterAnimations( List<Animator> animatiors ) {
        Animator aniAlpha = ObjectAnimator.ofFloat( mMorphChar.TextViewRef, "alpha", 0, 1 );
        aniAlpha.setDuration( mDuration );
        animatiors.add( aniAlpha );
    }

    // 默认动画，水平移动
    public void attachShiftAnimations( List<Animator> animatiors ) {
        int fromX = this.calXPos4FromIdx( mMorphChar.FromIdx );
        int toX = this.calXPos4ToIdx( mMorphChar.ToIdx );
        if ( fromX != toX ) {
            Animator aniXPos = ObjectAnimator.ofFloat( mMorphChar.TextViewRef, "x", fromX, toX );
            aniXPos.setDuration( mDuration );
            animatiors.add( aniXPos );
        }
    }

    public void attachAnimations( List<Animator> animatiors ) {
        switch ( mMorphChar.getLimboType( ) ) {
            case Enter:
                this.attachEnterAnimations( animatiors );
                break;
            case Leave:
                this.attachLeaveAnimations( animatiors );
                break;
            case Shift:
                this.attachShiftAnimations( animatiors );
                break;
        }
    }

    public ViewGroup.LayoutParams getStartupLayoutParas( ) {
        if ( this.mMorphChar.getLimboType( ) == LimboType.Enter )
            return new AbsoluteLayout.LayoutParams(
                    this.mMorphChar.TextViewRef.getMeasuredWidth( ), this.mMorphChar.TextViewRef.getMeasuredHeight( ),
                    this.calXPos4ToIdx( mMorphChar.ToIdx ), mExtraInfo.YPos );
        else
            return this.mMorphChar.TextViewRef.getLayoutParams( );
    }
}
